﻿@inject GlobalNotificationService GlobalNotificationService
@inject NavigationManager NavigationManager
@implements IDisposable

@if (Messages.Count == 0)
{
    return;
}

<div class="messages-container grid px-4 @(MarginTop ? "pt-6" : "") lg:gap-4 @(MarginBottom ? "pb-6" : "")">
    @foreach (var message in Messages)
    {
        if (message.Key == "success")
        {
            <AlertMessageSuccess Message="@message.Value" />
        }
    }
    @foreach (var message in Messages)
    {
        if (message.Key == "error")
        {
            <AlertMessageError Message="@message.Value" />
        }
    }
</div>

<style>
    .messages-container > :last-child {
        margin-bottom: 0 !important;
    }
</style>

@code {
    /// <summary>
    /// Whether to include top margin. Defaults to true.
    /// </summary>
    [Parameter]
    public bool MarginTop { get; set; } = true;

    /// <summary>
    /// Whether to include bottom margin.
    /// </summary>
    [Parameter]
    public bool MarginBottom { get; set; } = false;


    private List<KeyValuePair<string, string>> Messages { get; set; } = new();

    /// <inheritdoc />
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            RefreshAddMessages();
            GlobalNotificationService.OnChange += RefreshAddMessages;
            NavigationManager.LocationChanged += HandleLocationChanged;
        }
    }

    /// <inheritdoc />
    public void Dispose()
    {
        GlobalNotificationService.OnChange -= RefreshAddMessages;
        NavigationManager.LocationChanged -= HandleLocationChanged;
    }

    /// <summary>
    /// Refreshes the messages on navigation to another page.
    /// </summary>
    private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        RefreshAddMessages();
    }

    /// <summary>
    /// Refreshes the messages by adding any new messages from the PortalMessageService.
    /// </summary>
    private void RefreshAddMessages()
    {
        // We retrieve any additional messages from the GlobalNotificationService that we do not yet have.
        var newMessages = GlobalNotificationService.GetMessagesForDisplay();
        bool hasChanges = false;

        // Check for new messages
        foreach (var message in newMessages.Where(message => !Messages.Exists(m => m.Key == message.Key && m.Value == message.Value)))
        {
            Messages.Add(message);
            hasChanges = true;
        }

        // Check for messages to remove
        var messagesToRemove = Messages.Where(m => !newMessages.Exists(nm => nm.Key == m.Key && nm.Value == m.Value)).ToList();
        foreach (var message in messagesToRemove)
        {
            Messages.Remove(message);
            hasChanges = true;
        }

        // Only call StateHasChanged if there were actual changes
        if (hasChanges)
        {
            InvokeAsync(StateHasChanged);
        }
    }
}
